/*
 * Copyright (C) 2016, apexes.net. All rights reserved.
 * 
 *        http://www.apexes.net
 * 
 */
package net.apexes.wsonrpc.core;

import net.apexes.wsonrpc.json.JsonImplementor;
import net.apexes.wsonrpc.json.support.gson.GsonImplementor;

import java.util.concurrent.atomic.AtomicLong;

/**
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 */
public class WsonrpcConfigBuilder {

    public static WsonrpcConfig defaultConfig() {
        return create().build();
    }

    public static WsonrpcConfigBuilder create() {
        return new WsonrpcConfigBuilder();
    }

    private JsonImplementor jsonImpl;
    private BinaryWrapper binaryWrapper;
    private IdGenerater idGenerater;
    private WsonrpcLogger wsonrpcLogger;

    protected WsonrpcConfigBuilder() {
    }

    public WsonrpcConfig build() {
        if (jsonImpl == null) {
            jsonImpl = new GsonImplementor();
        }
        if (idGenerater == null) {
            idGenerater = new AtomicLongIdGenerater();
        }
        return new WsonrpcConfigImpl(jsonImpl, binaryWrapper, idGenerater, wsonrpcLogger);
    }

    /**
     * 设置使用的json工具，默认为 {@link GsonImplementor}
     * @param jsonImpl
     * @return
     */
    public WsonrpcConfigBuilder json(JsonImplementor jsonImpl) {
        this.jsonImpl = jsonImpl;
        return this;
    }

    /**
     * @param binaryWrapper
     * @return
     */
    public WsonrpcConfigBuilder wrapper(BinaryWrapper binaryWrapper) {
        this.binaryWrapper = binaryWrapper;
        return this;
    }

    /**
     * @param idGenerater
     * @return
     */
    public WsonrpcConfigBuilder idGenerater(IdGenerater idGenerater) {
        this.idGenerater = idGenerater;
        return this;
    }

    /**
     * @param wsonrpcLogger
     * @return
     */
    public WsonrpcConfigBuilder logger(WsonrpcLogger wsonrpcLogger) {
        this.wsonrpcLogger = wsonrpcLogger;
        return this;
    }

    /**
     *
     */
    protected static class WsonrpcConfigImpl implements WsonrpcConfig {

        private final JsonImplementor jsonImpl;
        private final BinaryWrapper binaryWrapper;
        private final IdGenerater idGenerater;
        private final WsonrpcLogger wsonrpcLogger;

        protected WsonrpcConfigImpl(WsonrpcConfig config) {
            this(config.getJsonImplementor(),
                    config.getBinaryWrapper(),
                    config.getIdGenerater(),
                    config.getWsonrpcLogger());
        }

        protected WsonrpcConfigImpl(JsonImplementor jsonImpl,
                                    BinaryWrapper binaryWrapper,
                                    IdGenerater idGenerater,
                                    WsonrpcLogger wsonrpcLogger) {
            this.jsonImpl = jsonImpl;
            this.binaryWrapper = binaryWrapper;
            this.idGenerater = idGenerater;
            this.wsonrpcLogger = wsonrpcLogger;
        }

        @Override
        public JsonImplementor getJsonImplementor() {
            return jsonImpl;
        }

        @Override
        public BinaryWrapper getBinaryWrapper() {
            return binaryWrapper;
        }

        @Override
        public IdGenerater getIdGenerater() {
            return idGenerater;
        }

        @Override
        public WsonrpcLogger getWsonrpcLogger() {
            return wsonrpcLogger;
        }
    }

    /**
     * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
     */
    private static class AtomicLongIdGenerater implements IdGenerater {

        private final AtomicLong currentId = new AtomicLong();

        @Override
        public String next() {
            return Long.toString(currentId.incrementAndGet());
        }
    }
}
